package internal

import (
	"fmt"
	"github.com/Sir-yuChen/funAnalyse/global"
	"go.uber.org/zap"
	"gorm.io/gorm/logger"
	"regexp"
	"strings"
)

type writer struct {
	logger.Writer
}

// NewWriter writer 构造函数
func NewWriter(w logger.Writer) *writer {
	return &writer{Writer: w}
}

// Printf 格式化打印日志 本方法 为了是gin打印的日志通过zap统一处理
func (w *writer) Printf(message string, data ...interface{}) {
	var logZap bool
	switch global.GVA_CONFIG.System.DbType {
	case "mysql":
		logZap = global.GVA_CONFIG.Mysql.LogZap
	}
	//自定义解析 gin log返回的sql打印信息 zap统一收集
	if logZap {
		var (
			zapSql           zap.Field
			zapCaller        zap.Field
			zapExecutionTime zap.Field
			zapNumber        zap.Field
		)
		for _, v := range data {
			sprintf := fmt.Sprintf("%v", v)
			if t, _ := regexp.MatchString(".go:[0-9]{1,}?", sprintf); t {
				zapCaller = zap.String("caller", sprintf)
				continue
			}
			if b := strContains(sprintf, []string{"where", "select", "delete", "update", "from", "group", "insert", "into"}); b {
				zapSql = zap.Any("sql", sprintf)
				continue
			}
			switch vt := v.(type) {
			case float64:
				zapExecutionTime = zap.Any("executionTime", vt)
				continue
			case int16:
			case int64:
				zapNumber = zap.Any("executionNumber", vt)
				continue
			default:
				global.GVA_LOG.Error("sql格式化 >>>> nil value: nothing to check?", zap.Any("params", v))
				continue
			}
		}
		global.GVA_LOG.Info("执行SQL>>>", zapCaller, zapSql, zapExecutionTime, zapNumber)
	} else {
		w.Writer.Printf(message, data...)
	}
}

func strContains(s string, strs []string) bool {
	for _, i := range strs {
		f := strings.Contains(strings.ToLower(s), i)
		if f {
			return f
		}
	}

	return false
}
